package com.yunyv.iotudpserve.TCP.listenerNew;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yunyv.iotudpserve.UDP.dto.TCPBo;
import com.yunyv.iotudpserve.utils.HexEcodeUtil;
import com.yunyv.iotudpserve.utils.HttpUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/********************************************************************************
 ** author： zhangtianhe
 ** date：2024年06月17日 14:36
 ** description&desc：
 *********************************************************************************/
@Slf4j
@Data
@Component
@NoArgsConstructor
public class SocketServer {
    private Integer port = 62011;
    private boolean started;
    private ServerSocket serverSocket;

    public void start(){
        log.info("port: {}, {}", this.port, port);
        try {
            serverSocket =  new ServerSocket(port == null ? this.port : port);
            started = true;
            log.info("Socket服务已启动，占用端口： {}", serverSocket.getLocalPort());
        } catch (IOException e) {
            log.error("端口冲突,异常信息：{}", e);
            System.exit(0);
        }
        System.out.println("服务器启动");
        while (true){
            //阻塞等待服务器与客户端建立连接
            Socket socket= null;
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            //若没线程 当一个客户端连接后 会一直在ProcessConnect内
            //其他客户端连接时 必须要等待ProcessConnect结束，进入下一次循环，才能执行到Socketsocket=serverSocket.accept(); 才能连接下一个客户端
//           // ProcessConnect(socket);


            //所以执行处理客户端请求，我们让线程去干，这样就不会在一个线程内阻塞
//            Thread thread=new Thread(()->{
//                try {
//                    ProcessConnect(socket);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            });
//            thread.start();

            //线程池
            ExecutorService executorService= Executors.newCachedThreadPool();
            Socket finalSocket = socket;
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        ProcessConnect(finalSocket);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }

    public void ProcessConnect(Socket socket) throws IOException {
        //实际他们交流数据是一个为socket类型的文件
        System.out.printf("[地址:%s:端口号%d]建立连接成功\n",socket.getInetAddress().toString(),socket.getPort());

        try ( InputStream inputStream = socket.getInputStream();//获取socket内部的input流
              OutputStream outputStream = socket.getOutputStream();)//获取socket内部的output流
        {
            Scanner scanner = new Scanner(inputStream);
            PrintWriter printWriter = new PrintWriter(outputStream);
            String info = "";
            String infoFile = "";
            //长连接写法
            while (true) {
                if(!scanner.hasNext()){
                    info = "";
                    String filePath = "deviceInfo.txt";
                    infoFile = "";
                    try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
                        writer.write(infoFile);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.printf("[地址:%s:端口号%d]断开连接",socket.getInetAddress().toString(),socket.getPort());
                }
                //从客户端接收数据
                String resqust = scanner.next();
                System.out.println("接收数据时间："+DateUtil.now()+"服务器接收数据"+resqust);
                chuli(resqust);
//                info+=resqust;
                infoFile= "服务器接收数据时间："+DateUtil.now() +infoFile+resqust;
                //处理数据
                String response = process(resqust);
                System.out.println("服务器处理数据");

                //因为这用流接收 我们按下换行是被scanner接收但并未添加到数据内 而服务器接收流收到的数据内
                //是没有换行符的 就会一直阻塞 所以我们要在数据后再加个\n
                //服务器发送数据
                //printWriter.write(response+'\n');
                //或者直接使用println自带\n
                printWriter.println(response);
                System.out.println("服务器发送数据");

                //刷新缓冲区
                printWriter.flush();
                System.out.printf("[地址:%s:端口号:%d]接收数据:%s 响应数据:%s",socket.getInetAddress().toString(),socket.getPort(),resqust,response);
            }
        }
    }

    private void chuli(String line){

        System.out.println("请求内容为："+line);
        TCPBo tcpBo = jiexiIot(line);
//        for (TCPBo tcpBo:tcpBos){
//            Map<String,String> header = new HashMap<String,String>();
//            header.put("Content-Type", "application/json");
//            //请求参数
//            Map<String,Object> param = new HashMap<String,Object>();
//            param.put("data",tcpBo);
//            String paramJson = JSONObject.toJSONString(param);
//
//            String result =  HttpUtil.postJson("http://127.0.0.1:8086/httpPublishTCP/sendTCP",header,paramJson);
//        }

        Map<String,String> header = new HashMap<String,String>();
        header.put("Content-Type", "application/json");
        //请求参数
        Map<String,Object> param = new HashMap<String,Object>();
        param.put("data",tcpBo);
        String paramJson = JSONObject.toJSONString(param);

        String result =  HttpUtil.postJson("http://127.0.0.1:8086/httpPublishTCP/send",header,paramJson);
    }
    public TCPBo jiexiIot(String srt){
//        List<TCPBo> boList  =new ArrayList<>();
        String deviceName="";//设备编号
        String deviceStatus="";//设备状态
        String devicesGsv="";//设备示值浓度
//        String srt = "#&868968072122089/003/4;MOD:WL136,0;GSV:1,30,%LEL,4;TPV:-20.5,C;PSV:323,Kpa,1;@8AAC";
        // 截取前十五位

        TCPBo tcpBo=new TCPBo();
        if (srt.length() > 15) {
            deviceName = srt.substring(0, 15);//设备名称
            String substring = srt.substring(15);//数据标识
            System.out.println(deviceName);
            JSONObject resultJson = JSONObject.parseObject(substring);
            JSONArray dataJson = resultJson.getJSONArray("sensorDatas");
            tcpBo.setDeviceName(deviceName);
            for (int a= 0;a<dataJson.size();a++){
                JSONObject device = (JSONObject) dataJson.get(a);
                if ("50".equals(device.getString("gas_type"))){
                    deviceStatus = device.getString("gas_status");
                    devicesGsv = device.getString("gas_value");
                    tcpBo.setDeviceStatus50(deviceStatus);
                    tcpBo.setDevicesGsv50(devicesGsv);
                }
                if ("5".equals(device.getString("gas_type"))){
                    deviceStatus = device.getString("gas_status");
                    devicesGsv = device.getString("gas_value");
                    tcpBo.setDeviceName(deviceName);
                    tcpBo.setDeviceStatus5(deviceStatus);
                    tcpBo.setDevicesGsv5(devicesGsv);
                }
                if ("4".equals(device.getString("gas_type"))){
                    deviceStatus = device.getString("gas_status");
                    devicesGsv = device.getString("gas_value");
                    tcpBo.setDeviceName(deviceName);
                    tcpBo.setDeviceStatus4(deviceStatus);
                    tcpBo.setDevicesGsv4(devicesGsv);
                }
                if ("3".equals(device.getString("gas_type"))){
                    deviceStatus = device.getString("gas_status");
                    devicesGsv = device.getString("gas_value");
                    tcpBo.setDeviceName(deviceName);
                    tcpBo.setDeviceStatus3(deviceStatus);
                    tcpBo.setDevicesGsv3(devicesGsv);
                }
            }
//            boList.add(tcpBo);
//            System.out.println(substring);
        } else {
            System.out.println("字符串长度不足十五位");
        }

//        String srt ="#&HBS030001001/001/3;DVS:1;GSV:1,0,%LEL,1;NTS:21,0;@74FE";
        return tcpBo;
    }
    public String process(String s){
        return s;
    }
}
